#ifndef prs_FrmValueRule_H
#define prs_FrmValueRule_H

#include "prs_Func.h"
#include "prs_Rule.h"
#include "prs_FrmRules.h"
//#include "prs_FrmNodes.h"
#include "prs_FrmValue.h"
#include "prs_FrmGeom.h"
#include "prs_FrmStyle.h"

namespace prs {
            
///////////////////////////////////////////////////////////////////////////////

struct TRuleFrmValue : public snt::TRule , public TFrmDict
{
  TRuleFrmValue(
    snt::text::TContext &Context,
    svl::TVariant &VParentNode,
    TRuleSetAttrValue &RSetAttrValue,
    TRuleFrmGeom &RFrmGeom,
    TRuleFrmChildrenBase &RFrmChildren
  );

  ///////////////////////////////
  struct TFuncAfterNewValueParams
  {
    TAttrNode *NewValue;
    svl::TString OutError;
    //
    TFuncAfterNewValueParams() { NewValue = NULL;}
  };
  typedef fastdelegate::FastDelegate<bool(TFuncAfterNewValueParams &Params)> TFuncAfterNewValue;

  /////////////////////////////////
  struct TFuncSetValueAsIdentParams
  {
    svl::TString Ident;
    svl::TString OutError;
    //
    TFuncSetValueAsIdentParams() {}
  };
  typedef fastdelegate::FastDelegate<bool(TFuncSetValueAsIdentParams &Params)> TFuncSetValueAsIdent;

  ////////////
  struct TFunc
  {
    TFunc() {}
    //
    template<class PObj,class PFunc> TFunc &BindFuncAfterNewValue(PObj pObj,PFunc pFunc) {
      funcAfterNewValue.bind(pObj,pFunc); return *this;
    }
    template<class PObj,class PFunc> TFunc &BindFuncSetValueAsIdent(PObj pObj,PFunc pFunc) {
      funcSetValueAsIdent.bind(pObj,pFunc); return *this;
    }
  
  private:
    TFuncAfterNewValue funcAfterNewValue;
    TFuncSetValueAsIdent funcSetValueAsIdent;
    friend TRuleFrmValue;
  };
  
  ////////////////
  snt::TRule &New(
    const char *AttrName,
    TFunc &Func = TFunc()
  );

private:
  struct TRuleParam : public svl::TPointer
  {
    svl::TString AttrName;
    TFuncAfterNewValue FuncAfterNewValue;
    TFuncSetValueAsIdent FuncSetValueAsIdent;
  };
  //
  TRuleParam *GetRuleParams() { return static_cast<TRuleParam*>(snt::TRule::GetParams());}
  //
  virtual bool EnEntry();
  //
  bool FSetParam(TRuleSetAttrValue::TFuncValueIdentParams &Params);
  //
  bool afterNewValue(svl::TString &OutError);
  bool FAfterNewValue(snt::text::TSequence::TFuncClosureDoEntryParams &Params);
  //
  bool FSetValueString (snt::text::TString::TFuncClosureDoEntryParams &Params);
  bool FSetValueNumber (snt::text::TNumber::TFuncClosureDoEntryParams &Params);
  bool FSetValueDouble (sntText::TDouble::TFuncClosureDoEntryParams &Params);
  bool FSetValueAsIdent(snt::text::TIdent ::TFuncClosureDoEntryParams &Params);
  bool FSetValueBool   (snt::text::TSequence::TFuncClosureDoEntryParams &Params);
  //
  void FSetAttrValueIntoFrmGeomSizeValue(snt::TParams &Params);
  void FSetAttrValueIntoFrmGeomDirectValue(snt::TParams &Params);
  void FSetAttrValueIntoFrmGeomWAlignValue(snt::TParams &Params);
  void FSetAttrValueIntoFrmGeomHAlignValue(snt::TParams &Params);
  //
  bool FSetStyle(snt::text::TIdent::TFuncClosureDoEntryParams &Params);
  //
  svl::TVariant &vParentNode;
  TRuleFrmGeom &rFrmGeom;
  svl::TString attrName;
  svl::TVariant vEnSetValueAsIdent;
  snt::TRule R1;
  snt::TAlter A1,ABool;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
}

#endif
